package com.example.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import com.example.ccubee.common.exception.DemoException;
import com.example.contant.RedisKeyConstant;
import com.example.entity.SkillGoods;
import com.example.entity.SkillOrder;
import com.example.mapper.SkillGoodsMapper;
import com.example.mapper.SkillOrderMapper;
import com.example.utils.RedisLock;
import io.lettuce.core.RedisException;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author ccubee
 * @since 2021/8/26 19:54
 */
@Service
@RequiredArgsConstructor
public class TestServiceRedis {

    private final SkillGoodsMapper skillGoodsMapper;
    private final SkillOrderMapper skillOrderMapper;
    private final SkillGoodsService skillGoodsService;
    private final RedissonClient redissonClient;
    private final RedisTemplate redisTemplate;
    private static final int TIMEOUT = 10 * 1000; // 10秒钟
    private final DefaultRedisScript defaultRedisScript;

    @Transactional(rollbackFor = Exception.class)
    public void test(String userId, Long productId) {
        userId = UUID.fastUUID().toString(true);
//        String key = RedisKeyConstant.SKILL_GOOD + productId;

//        Map<String, Object> map = redisTemplate.opsForHash().entries(key);
//        SkillGoods skillGoods = BeanUtil.mapToBean(map, SkillGoods.class, true, null);
//        SkillGoods skillGoods = (SkillGoods) redisTemplate.boundHashOps(RedisKeyConstant.SKILL_GOODS_SIGN).get(productId);
        SkillGoods skillGoods = skillGoodsMapper.selectById(productId);
        if (null == skillGoods) {
            throw new RedisException("活动已卖光");
        }
        if (0 == skillGoods.getStockCount()) {
            throw new DemoException("已卖完");
        }

        String lockName = RedisKeyConstant.LOCK_KEY + productId + "" ;
        RLock lock = redissonClient.getLock(lockName);
        // 下单
        try {
            boolean isLock = lock.tryLock(10000, TimeUnit.MILLISECONDS);
            if (isLock) {
                SkillOrder order = SkillOrder.builder()
                        .skillId(productId)
                        .userId(userId)
                        .createTime(LocalDateTime.now())
                        .build();
                skillOrderMapper.insert(order);
                // 扣库存
                skillGoodsService.test(skillGoods);


//                List<String> keys = new ArrayList<>();
//                keys.add(key);
//                keys.add("stock_count");
//                Long amount = (Long) redisTemplate.execute(defaultRedisScript, keys);
//                if (amount == null || amount < 1 ){
//                    skillGoodsService.test(skillGoods);
//                    throw new DemoException("卖完了");
//                }
            }
        } catch (InterruptedException e) {
            // 手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            // 解锁
            lock.unlock();
            throw new DemoException("已经抢购过了");
        }


    }
}
